package com.ruoyi.ftrl.service.impl;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.ftrl.domain.Dto.Category;
import com.ruoyi.ftrl.domain.Dto.DateDto;
import com.ruoyi.ftrl.domain.Dto.TempDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.ftrl.mapper.WeatherMapper;
import com.ruoyi.ftrl.domain.Weather;
import com.ruoyi.ftrl.service.IWeatherService;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * 实时天气预报Service业务层处理
 * 
 * @author dihang
 * @date 2024-08-05
 */
@Service
public class WeatherServiceImpl implements IWeatherService 
{
    @Autowired
    private WeatherMapper weatherMapper;

    /**
     * 查询实时天气预报
     * 
     * @param id 实时天气预报主键
     * @return 实时天气预报
     */
    @Override
    public Weather selectWeatherById(Long id)
    {
        return weatherMapper.selectWeatherById(id);
    }

    /**
     * 查询实时天气预报列表
     * 
     * @param weather 实时天气预报
     * @return 实时天气预报
     */
    @Override
    public List<Weather> selectWeatherList(Weather weather)
    {
        return weatherMapper.selectWeatherList(weather);
    }

    /**
     * 新增实时天气预报
     * 
     * @param weather 实时天气预报
     * @return 结果
     */
    @Override
    public int insertWeather(Weather weather)
    {
        weather.setCreateTime(DateUtils.getNowDate());
        return weatherMapper.insertWeather(weather);
    }

    /**
     * 修改实时天气预报
     * 
     * @param weather 实时天气预报
     * @return 结果
     */
    @Override
    public int updateWeather(Weather weather)
    {
        weather.setUpdateTime(DateUtils.getNowDate());
        return weatherMapper.updateWeather(weather);
    }

    /**
     * 批量删除实时天气预报
     * 
     * @param ids 需要删除的实时天气预报主键
     * @return 结果
     */
    @Override
    public int deleteWeatherByIds(Long[] ids)
    {
        return weatherMapper.deleteWeatherByIds(ids);
    }

    /**
     * 删除实时天气预报信息
     * 
     * @param id 实时天气预报主键
     * @return 结果
     */
    @Override
    public int deleteWeatherById(Long id)
    {
        return weatherMapper.deleteWeatherById(id);
    }

    private static final String apiKey = "SR1EhRUJANDu9DiZq";
    private static final String url = "https://api.seniverse.com/v3/weather/now.json?key=" + apiKey + "&location=baoding&language=zh-Hans&unit=c";
    /**
     * 定时拉取实时天气预报并数据入库
     */
    @Override
    public String fetchAndSaveWeather() {

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity);
                    JSONObject jsonObject = new JSONObject(result);
                    JSONArray resultsArray = jsonObject.getJSONArray("results");

                    if (resultsArray.length() > 0) {
                        JSONObject locationObject = resultsArray.getJSONObject(0);
                        JSONObject location = locationObject.getJSONObject("location");
                        JSONObject now = locationObject.getJSONObject("now");
                        System.out.println(location);
                        System.out.println(now);

                        Weather weather = new Weather();
                        weather.setCityId(location.getString("id"));
                        weather.setCityName(location.getString("name"));
                        weather.setCountry(location.getString("country"));
                        weather.setPath(location.getString("path"));
                        weather.setTimezone(location.getString("timezone"));
                        weather.setTimezoneOffset(location.getString("timezone_offset"));
                        weather.setWeatherText(now.getString("text"));
                        weather.setWeatherCode(now.getString("code"));
                        weather.setTemperature(now.getString("temperature"));
                        weather.setFeelsLike(now.getString("feels_like"));
                        weather.setPressure(now.getString("pressure"));
                        weather.setHumidity(now.getString("humidity"));
                        weather.setVisibility(now.getString("visibility"));
                        weather.setWindDirection(now.getString("wind_direction"));
                        weather.setWindDirectionDegree(now.getString("wind_direction_degree"));
                        weather.setWindSpeed(now.getString("wind_speed"));
                        weather.setWindScale(now.getString("wind_scale"));
                        weather.setClouds(now.optString("clouds", "N/A"));
                        weather.setDewPoint(now.optString("dew_point", "N/A"));
                        weather.setCreateTime(new Date());
                        // 使用java.time包来解析日期字符串
                        var formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
                        OffsetDateTime offsetDateTime = OffsetDateTime.parse(locationObject.getString("last_update"), formatter);
                        Date lastUpdate = Date.from(offsetDateTime.toInstant());
                        weather.setLastUpdate(lastUpdate);

                        weatherMapper.insertWeather(weather);

                        return "Weather data saved successfully!";
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "Failed to fetch weather data.";
        }
        return "No weather data available.";
    }


    /**
     * 平均室外温度历史曲线(保定市整体地区)
     */
    @Override
    public TempDto selectWeatherListCurve(DateDto dateDto) {

        TempDto tempDto = new TempDto();

        List<String> roomNos = dateDto.getRoomNos();
        LocalDate startDate;
        LocalDate endDate;

        if (dateDto.getStartTime() == null && dateDto.getEndTime() == null) {
            // 没有输入开始时间和结束时间，默认查询过去一周的数据
            LocalDate today = LocalDate.now();
            endDate = today;
            startDate = today.minusDays(6);
        } else {
            // 输入了开始时间和结束时间
            endDate = dateDto.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            startDate = dateDto.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        }

        // 构建日期列表
        List<Date> dates = new ArrayList<>();
        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            //LocalDate类型转化为Date类型
            dates.add(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()));
        }
        //X日期横坐标
        tempDto.setTime(dates);
        //标题名称
        List<String> names = new ArrayList<>();
        names.add("平均室外温度");
        tempDto.setName(names);
        //温度曲线
        List<Category> categoryList = new ArrayList<>();
        Category category = new Category();
        category.setName("平均室外温度");
        category.setType("line");
        category.setData(new ArrayList<>());
        for (Date date : dates) {
            Map<String, Object> params = new HashMap<>();
            String formattedDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate().toString();
            params.put("date", formattedDate);
            Long temperature = weatherMapper.selectWeatherListByTimes(params);
            if (temperature != null) {
                category.getData().add(temperature);
            } else {
                category.getData().add(0l);
            }
        }
        categoryList.add(category);
        tempDto.setCategoryList(categoryList);

        return tempDto;
    }

    /**
     * 获取昨天、今天以及未来两天的天气预报
     */
    @Override
    public Object selectWeatherListFuture() {
        //昨天、今天以及未来两天的天气预报
        // API密钥
        String apiKey = "SR1EhRUJANDu9DiZq";
        // API请求URL
        String url = "https://api.seniverse.com/v3/weather/daily.json?key=SR1EhRUJANDu9DiZq&location=baoding&language=zh-Hans&unit=c&start=-1&days=4";

        // 创建HTTP客户端
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 创建HTTP GET请求
            HttpGet httpGet = new HttpGet(url);

            // 发送请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    // 将响应内容转换为字符串
                    String result = EntityUtils.toString(entity);
                    // 解析JSON响应
                    cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(result);
                    cn.hutool.json.JSONArray dailyArray = jsonObject.getJSONArray("results")
                            .getJSONObject(0)
                            .getJSONArray("daily");
                    return dailyArray;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Weather selectWeatherByIdActual() {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity);
                    JSONObject jsonObject = new JSONObject(result);
                    JSONArray resultsArray = jsonObject.getJSONArray("results");

                    if (resultsArray.length() > 0) {
                        JSONObject locationObject = resultsArray.getJSONObject(0);
                        JSONObject location = locationObject.getJSONObject("location");
                        JSONObject now = locationObject.getJSONObject("now");
                        System.out.println(location);
                        System.out.println(now);

                        Weather weather = new Weather();
                        weather.setCityId(location.getString("id"));
                        weather.setCityName(location.getString("name"));
                        weather.setCountry(location.getString("country"));
                        weather.setPath(location.getString("path"));
                        weather.setTimezone(location.getString("timezone"));
                        weather.setTimezoneOffset(location.getString("timezone_offset"));
                        weather.setWeatherText(now.getString("text"));
                        weather.setWeatherCode(now.getString("code"));
                        weather.setTemperature(now.getString("temperature"));
                        weather.setFeelsLike(now.getString("feels_like"));
                        weather.setPressure(now.getString("pressure"));
                        weather.setHumidity(now.getString("humidity"));
                        weather.setVisibility(now.getString("visibility"));
                        weather.setWindDirection(now.getString("wind_direction"));
                        weather.setWindDirectionDegree(now.getString("wind_direction_degree"));
                        weather.setWindSpeed(now.getString("wind_speed"));
                        weather.setWindScale(now.getString("wind_scale"));
                        weather.setClouds(now.optString("clouds", "N/A"));
                        weather.setDewPoint(now.optString("dew_point", "N/A"));
                        weather.setCreateTime(new Date());
                        // 使用java.time包来解析日期字符串
                        var formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
                        OffsetDateTime offsetDateTime = OffsetDateTime.parse(locationObject.getString("last_update"), formatter);
                        Date lastUpdate = Date.from(offsetDateTime.toInstant());
                        weather.setLastUpdate(lastUpdate);

//                        weatherMapper.insertWeather(weather);

                        return weather;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

//                    // 遍历解析的天气数据
//                    for (int i = 0; i < dailyArray.size(); i++) {
//                        cn.hutool.json.JSONObject dayWeather = dailyArray.getJSONObject(i);
//                        String date = dayWeather.getStrEscaped("date");
//                        String textDay = dayWeather.getStrEscaped("text_day");
//                        String codeDay = dayWeather.getStrEscaped("code_day");
//                        String textNight = dayWeather.getStrEscaped("text_night");
//                        String codeNight = dayWeather.getStrEscaped("code_night");
//                        String highTemp = dayWeather.getStrEscaped("high");
//                        String lowTemp = dayWeather.getStrEscaped("low");
//                        String precip = dayWeather.getStrEscaped("precip");
//                        String windDirection = dayWeather.getStrEscaped("wind_direction");
//                        String windDirectionDegree = dayWeather.getStrEscaped("wind_direction_degree");
//                        String windSpeed = dayWeather.getStrEscaped("wind_speed");
//                        String windScale = dayWeather.getStrEscaped("wind_scale");  // 使用optString来避免空值报错
//                        String rainfall = dayWeather.getStrEscaped("rainfall");
//                        String humidity = dayWeather.getStrEscaped("humidity");
//
//                        System.out.println("日期: " + date);
//                        System.out.println("白天天气: " + textDay);
//                        System.out.println("白天天气代码: " + codeDay);
//                        System.out.println("夜间天气: " + textNight);
//                        System.out.println("夜间天气代码: " + codeNight);
//                        System.out.println("最高温度: " + highTemp);
//                        System.out.println("最低温度: " + lowTemp);
//                        System.out.println("降水概率: " + precip);
//                        System.out.println("风向: " + windDirection);
//                        System.out.println("风向角度: " + windDirectionDegree);
//                        System.out.println("风速: " + windSpeed);
//                        System.out.println("风力等级: " + windScale);
//                        System.out.println("降水量: " + rainfall);
//                        System.out.println("湿度: " + humidity);
//                        System.out.println("----------------------------------");
//                    }


}

